package org.rainbowinverted.charging.device.connect.bl.server.decode;

import cn.hutool.core.util.HexUtil;
import com.dix.codec.bkv.BKV;
import com.dix.codec.bkv.KV;
import com.dix.codec.bkv.UnpackBKVResult;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.rainbowinverted.charging.device.api.operation.constants.DeviceOpConstantEnum;
import org.rainbowinverted.charging.device.connect.bl.server.handler.BlAbstractHandler;
import org.rainbowinverted.charging.device.connect.bl.server.handler.BlHandlerFactory;
import org.rainbowinverted.charging.device.connect.bl.server.message.out.BlDeviceMessageOut;
import org.rainbowinverted.charging.device.connect.bl.server.util.BlOpCodeMap;
import org.springframework.stereotype.Component;


import java.util.List;
import java.util.Objects;

/**
 * 柏来bkv解码器
 *
 * @author huaiping
 */
@Slf4j
@Component
@ChannelHandler.Sharable
public class BlBkvDecoder extends MessageToMessageDecoder<ByteBuf> {

    @Resource
    private BlHandlerFactory blHandlerFactory;

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        // 可读字节
        int length = byteBuf.readableBytes();
        // 读取字节数组声明
        byte[] byteMessage = new byte[length];
        byteBuf.readBytes(byteMessage);
        // byte转十六进制字符串
        String hexMessage = HexUtil.encodeHexStr(byteMessage);
        // 十六进制转BKV
        // 用户数据区，从第5个字节开始，到倒数第四个字节为止
        String dataHex = hexMessage.substring(4 * 2, hexMessage.length() - 6);
        // BKV解析
        UnpackBKVResult unpack = BKV.unpack(HexUtil.decodeHex(dataHex));
        BKV bkv = unpack.getBKV();
        // 功能码
        KV opCodeKv = bkv.get(1);
        int opCode = Integer.parseInt(HexUtil.encodeHexStr(opCodeKv.getValue()), 16);
        // 业务解码器处理
        BlAbstractHandler<?, BlDeviceMessageOut> blHandler = blHandlerFactory.getHandler(
                BlOpCodeMap.convertOpCodeToPlatformCode(opCode));
        if (Objects.isNull(blHandler)) {
            log.error("没有找到匹配的handler，opCode: {}", Long.toHexString(opCode));
        }
        log.info("recv message, opCode: {}, hex: {}", Long.toHexString(opCode), hexMessage);
        blHandler.read(channelHandlerContext, bkv);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        blHandlerFactory.getHandler(DeviceOpConstantEnum.DISCONNECT.getOpCode()).read(ctx, null);
        super.channelInactive(ctx);
    }
}
